package com.woniu.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.entity.ManagerRole;
import com.woniu.entity.RoleUrlPermission;
import com.woniu.entity.UrlPermission;
import com.woniu.mapper.ManagerRoleMapper;
import com.woniu.mapper.RoleUrlPermissionMapper;
import com.woniu.mapper.UrlPermissionMapper;
import com.woniu.service.UrlPermissionService;
import com.woniu.service.vo.PermissionShow;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单和接口权限定义 服务实现类
 * </p>
 *
 * @author D
 * @since 2023-03-27 08:24:57
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UrlPermissionServiceImpl extends ServiceImpl<UrlPermissionMapper, UrlPermission> implements UrlPermissionService {

    @Resource
    UrlPermissionMapper urlPermissionMapper;
    @Resource
    RoleUrlPermissionMapper roleUrlPermissionMapper;
    @Resource
    ManagerRoleMapper managerRoleMapper;

    /**
     * 根据用户code查询权限列表，
     * @param managerId 用户code
     * @return 返回PermissionShow类型的list
     */
    @Override
    public List<PermissionShow> selectListById(Long managerId) {
        // 根据角色id查询关联表，判断角色是否有权限，如果有再查询相关权限，存入roleUrlVo
        QueryWrapper<ManagerRole> managerRoleWrapper = new QueryWrapper<>();
        managerRoleWrapper.eq("manager_id", managerId);
        Set<Long> roleIdsSet = managerRoleMapper.selectList(managerRoleWrapper).stream()
                .map(managerRole -> {
                    return managerRole.getRoleId();
                }).collect(Collectors.toSet());

        QueryWrapper<RoleUrlPermission> roleUrlPermissionWrapper = new QueryWrapper<>();
        roleUrlPermissionWrapper.in("role_id", roleIdsSet);
        Set<Long> roleUrlPermissionIdSet = roleUrlPermissionMapper.selectList(roleUrlPermissionWrapper)
                .stream().map(roleUrlPermission -> {
                    return roleUrlPermission.getUrlPermissionId();
                }).collect(Collectors.toSet());

        QueryWrapper<UrlPermission> urlPermissionWrapper = new QueryWrapper<>();
        urlPermissionWrapper.in("id", roleUrlPermissionIdSet);
        List<PermissionShow> list = list(urlPermissionWrapper);
        return list;
    }

    /**
     * 查询所有菜单权限
     * @return 返回PermissionShow类型的list
     */
    @Override
    public List<PermissionShow> selectList() {
        QueryWrapper<UrlPermission> urlPermissionWrapper = new QueryWrapper<>();
        List<PermissionShow> list = list(urlPermissionWrapper);
        return list;
    }

    /**
     * 查询菜单权限并转换为PermissionShow list，存入hashmap，判断是否有父菜单权限
     * @param wrapper 实体对象封装操作类
     * @return 返回PermissionShow类型的list
     */
    public List<PermissionShow> list(Wrapper wrapper) {
        List<UrlPermission> urlPermissionList = urlPermissionMapper.selectList(wrapper);
        // 将urlPermissionList转换为PermissionShow list
        List<PermissionShow> permissionShowList = urlPermissionList.stream().map(permission -> {
            PermissionShow permissionShow = new PermissionShow();
            permissionShow.setId(permission.getId()).setName(permission.getName())
                    .setParentId(permission.getParentId()).setUrl(permission.getUrl())
                    .setChildren(new ArrayList<>());
            return permissionShow;
        }).collect(Collectors.toList());

        HashMap<Long, PermissionShow> map = new HashMap<>();
        permissionShowList.forEach(permissionShow -> {
            map.put(permissionShow.getId(), permissionShow);
        });

        map.forEach((id, permissionShow) -> {
            PermissionShow parent = map.get(permissionShow.getParentId());
            if (parent != null) {
                parent.getChildren().add(permissionShow);
            }
        });

        List<PermissionShow> showList = map.values().stream().filter(permissionShow -> {
            return permissionShow.getParentId() == -1;
        }).collect(Collectors.toList());
        return showList;

    }

    /**
     * 根据角色id查询绑定权限关系表，将权限id存入set
     *
     * @param roleId 角色id
     * @return 返回Set<Long>类型的权限id集合
     */
    @Override
    public Set<Long> getPermissionIds(Long roleId) {
        QueryWrapper<RoleUrlPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        List<RoleUrlPermission> roleUrlPermissionList = roleUrlPermissionMapper.selectList(wrapper);
        Set<Long> permissionIds = roleUrlPermissionList.stream().map(roleUrlPermission -> {
            return roleUrlPermission.getUrlPermissionId();
        }).collect(Collectors.toSet());
        return permissionIds;

    }

    /**
     * 给角色配置权限
     *
     * @param roleId       角色id
     * @param permissionIds 权限id数组
     */
    @Override
    public void addAuthority(Long roleId, Long[] permissionIds) {
        QueryWrapper<RoleUrlPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        roleUrlPermissionMapper.delete(wrapper);
        if (permissionIds.length > 0) {
            roleUrlPermissionMapper.addAuthority(roleId, permissionIds);
        }
    }

    /**
     * 分页查询UrlPermission列表
     *
     * @param currentPage 当前页码
     * @param pageSize    每页记录数
     * @param keyword     关键词
     * @return 返回Page<UrlPermission>类型的分页结果
     */
    @Override
    public Page<UrlPermission> pageList(Integer currentPage, Integer pageSize, String keyword) {
        Page<UrlPermission> page = new Page<>(currentPage, pageSize);
        QueryWrapper<UrlPermission> urlPermissionWrapper = new QueryWrapper<>();
        if (keyword != null && !"".equals(keyword)) {
            urlPermissionWrapper.like("name", keyword);
        }
        Page<UrlPermission> urlPermissionPage = urlPermissionMapper.selectPage(page, urlPermissionWrapper);
        return urlPermissionPage;
    }

    /**
     * 删除权限菜单及子菜单，并删除相关数据
     *
     * @param permissionId 权限菜单id
     */
    @Override
    public void deleteById(Long permissionId) {
        QueryWrapper<UrlPermission> urlPermissionWrapper = new QueryWrapper<>();
        urlPermissionWrapper.eq("parent_id", permissionId);
        List<UrlPermission> childrenList = urlPermissionMapper.selectList(urlPermissionWrapper);
        if (childrenList.size()>0){
            for (UrlPermission urlPermission : childrenList) {
                deleteById(urlPermission.getId());
            }
        }

        urlPermissionMapper.deleteById(permissionId);

        QueryWrapper<RoleUrlPermission> wrapper = new QueryWrapper<>();
        wrapper.eq("url_permission_id", permissionId);
        roleUrlPermissionMapper.delete(wrapper);
    }


}
